<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>java面向对象的多态理解</title>
  <!-- 
  在Java中，面向对象的多态（Polymorphism）是一种重要的特性，它允许对象以多种形式出现。多态性使得同一操作可以作用于不同类型的对象，提供了更大的灵活性和可扩展性。
  1. 多态的基本概念
  多态可以理解为“多种形态”。在Java中，多态主要通过以下两种方式实现：

  - 方法重载（Compile-time Polymorphism）：同一个方法名可以根据不同的参数类型或数量进行重载。
  - 方法重写（Runtime Polymorphism）：子类可以重写父类的方法，允许在运行时根据对象的实际类型调用相应的方法。

  2. 方法重载

  方法重载是指在同一个类中，允许存在多个同名但参数不同的方法。编译器根据方法的参数类型和数量来决定调用哪个方法。
  class MathUtils {
      // 加法方法重载
      public int add(int a, int b) {
          return a + b;
      }

      public double add(double a, double b) {
          return a + b;
      }

      public int add(int a, int b, int c) {
          return a + b + c;
      }
  }
  3. 方法重写

  方法重写发生在子类中，子类可以提供父类方法的具体实现。运行时，Java虚拟机会根据对象的实际类型来决定调用哪个方法，这就是运行时多态。
  class Animal {
      public void sound() {
          System.out.println("Animal makes a sound");
      }
  }

  class Dog extends Animal {
      @Override
      public void sound() {
          System.out.println("Dog barks");
      }
  }

  class Cat extends Animal {
      @Override
      public void sound() {
          System.out.println("Cat meows");
      }
  }
  4. 多态的实现

  多态通常通过父类引用指向子类对象来实现。这样可以在运行时调用子类的重写方法。
  public class Main {
      public static void main(String[] args) {
          Animal myDog = new Dog();
          Animal myCat = new Cat();

          myDog.sound(); // 输出: Dog barks
          myCat.sound(); // 输出: Cat meows
      }
  }
  5. 多态的优点

  - 灵活性：多态允许程序在运行时决定调用哪个方法，增强了程序的灵活性。
  - 可扩展性：可以通过增加新的子类而不需要修改现有代码来扩展程序。
  - 代码重用：通过父类引用可以使用子类对象，减少了代码的重复。

  6. 总结

  Java中的多态是面向对象编程的核心特性之一，它通过方法重载和重写实现了灵活的代码设计。多态不仅提高了代码的可读性和可维护性，还使得程序具有更好的扩展性。在实际开发中，合理利用多态性可以大大提高代码的质量和灵活性。
   -->
</head>
<body>

  <script>
    // java面向对象的多态理解
    // 多态：同一个方法，不同的对象，不同的行为
    // 多态：同一个方法，不同的对象，不同的表现形式
    // 多态：同一个方法，不同的对象，不同的结果
    // 多态的体现：父类引用指向子类对象，调用方法，执行的是子类重写的方法

    // 1. 继承是多态的前提
    // shape 形状
    class Shape {
      draw() {
        console.log('draw shape');
      }
    }

    class Rectangle extends Shape {
      constructor(width, height) {
        super();
        this.width = width;
        this.height = height;
      }
      draw() {
        console.log('draw rectangle');
        return this.width * this.height;
      }
    }

    class Circle extends Shape {
      constructor(radius) {
        super();
        this.radius = radius;
      }
      draw() {
        console.log('draw circle');
        return Math.PI * this.radius * this.radius;
      }
    }

    // 2. 父类引用指向子类对象
    let shape1 = new Rectangle(10, 20);
    let shape2 = new Circle(5);

    // 3. 调用方法，执行的是子类重写的方法
    shape1.draw();
    shape2.draw();
    console.log(shape1.draw()); // 200
    console.log(shape2.draw()); // 78.53981633974483

    // 表现形式就是多态
    /*
      在严格意义的面向对象语言中, 多态的是存在如下条件的:
        1.必须有继承(实现接口)
        2.必须有父类引用指向子类对象
    */
    function getShapeArea(shape) {
      console.log(shape.draw())
    }

    getShapeArea(shape1)
    getShapeArea(shape2)

    
    var obj = {
      draw: function() {
        return 10000
      }
    }

    getShapeArea(obj)
    
  </script>
  
</body>
</html>